package com.lhy.admin.common.mvcplus.wrapper.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lhy.admin.common.mvcplus.entity.ComparatorEnum;
import com.lhy.admin.common.mvcplus.entity.DbField;
import com.lhy.admin.common.mvcplus.wrapper.AbstractSearchComparator;
import com.lhy.admin.util.ReflectionUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * JSONArrayContainsComparator
 *
 * @author hyluan
 * @date 2022年11月21日 14:11
 */
public class JSONArrayContainsComparator extends AbstractSearchComparator {

    public static final String JSON_CONTAINS_ARRAY_SQL_TEMP = "JSON_CONTAINS(%s,JSON_ARRAY({0}))";

    @Override
    public void accept(QueryWrapper queryWrapper, DbField dbField) {
        //获取字段数据类型
        Class fieldClass = getAttrFieldClass(queryWrapper, dbField.getName());
        queryWrapper.nested(qw -> {
            QueryWrapper qw1 = (QueryWrapper) qw;
            String[] vals = splitStr(dbField.getValue());
            for (int i = 0; i < vals.length; i++) {
                Object value = Convert.convert(fieldClass, vals[i]);
                qw1.apply(sql(dbField.getName()), value);
                if (i < vals.length - 1) {
                    qw1.or();
                }
            }
        });
    }

    @Nullable
    private Class getAttrFieldClass(QueryWrapper queryWrapper, String dbFieldName) {
        Field field = ReflectionUtils.getFieldByDbFieldName(queryWrapper.getEntityClass(), dbFieldName);
        ParameterizedType genericType = (ParameterizedType) field.getGenericType();
        Assert.isTrue(((Class) genericType.getRawType()).isAssignableFrom(List.class), "JSON_CONTAINS 字段：%s必须为List".formatted(dbFieldName));
        Class<Object> objectClass = ReflectionUtils.getParameterizedType(genericType, 0);
        return objectClass;
    }

    public static String sql(String colName) {
        return JSON_CONTAINS_ARRAY_SQL_TEMP.formatted(colName);
    }

    @Override
    public ComparatorEnum comparatorEnum() {
        return ComparatorEnum.JSON_ARRAY_CONTAINS;
    }
}
